#pragma once

#include "TcpServer.hpp"
#include "Protocol.hpp"

#include <memory>
#include <signal.h>

using namespace NS_TcpServer;
using namespace NS_Protocol;

#define ADD '+'
#define SUB '-'
#define MUL '*'
#define DIV '/'
#define MOD '%'

// 计算器逻辑
static Response calculatorHelper(const Request& req)
{
    Response resp(req._x, req._y, req._op, 0, 0);
    switch(req._op)
    {
        case ADD:
            resp._result = req._x + req._y;
            break;
        case SUB:
            resp._result = req._x - req._y;
            break;
        case MUL:
            resp._result = req._x * req._y;
            break;
        case DIV:
            if(resp._y == 0) resp._code = 1;
            else resp._result = req._x / req._y;
            break;
        case '%':
            if(resp._y == 0) resp._code = 2;
            else resp._result = req._x % req._y;
            break;
        default:
            resp._code = 3;
            break;
    }

    return resp;
}

void calculator(int sock)
{
    std::string inBuffer;
    while(true)
    {
        // 1. 接收数据
        bool res = Recv(sock, &inBuffer);
        if(!res)    
            break;

        // 2.  协议解析，获取报文
        std::string package = Decode(inBuffer);
        if(package.empty()) continue;
        logMessage(NORMAL, "%s", package.c_str()); // 日志输出

        // 3. 保证报文完整
        Request req;
        // 4. 反序列化
        req.Deserialize(package);
        // 5. 业务处理
        Response resp = calculatorHelper(req);
        // 6. 序列化
        std::string outBuffer = resp.Serialize();
        // 7. 添加长度信息: 形成完整报文
        /* "length\r\ncode result\r\n" */
        outBuffer = Encode(outBuffer);
        // 8. 发送结果
        Send(sock, outBuffer);

    }
    
}

int main(int argc, char* argv[])
{
    if(argc != 2)
    {
        std::cout << "Usage: " << argv[0] << " port" << std::endl;
        exit(1);
    }
    // 创建服务器对象
    std::unique_ptr<TcpServer> server(new TcpServer(atoi(argv[1])));
    server->BindService(calculator);
    server->Start();

    return 0;
}